﻿// Learn more about F# at http://fsharp.net

module StochasticSimulation.GillespieFirstAlgorithm.Tests

open System
open StochasticSimulation.ChemicalReaction.ChemicalReaction
open StochasticSimulation.ChemicalReaction.ChemicalSpecies
open StochasticSimulation.GillespieFirstAlgorithm
open NUnit.Framework

[<TestFixture>]
type ``Gillespie First Algorithm Tests``() = class

    let system = 
        [ {Species = { Name ="I" } ; Count = 0 };
        {Species = { Name ="S" } ; Count =  10 };
        {Species = { Name ="P" } ; Count = 100 } ] :> seq<SpeciesCount>

    [<Test>]
    member self.`` pick the reaction with the smallest next reaction time.``() =
        let rnd = new Random(100)
        let reactions = [ 
            { Rate = 1000.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0} ; {Name = "P"}, {Destroyed =0 ; Created=1} ] };
            { Rate = 1.0 ; Changes = dict[ {Name = "P"}, {Destroyed =1 ; Created=0}] };
            { Rate = 9900.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0} ; {Name = "S"}, {Destroyed =1 ; Created=1} ] };
            { Rate = 10000.0 ; Changes = dict[ {Name = "S"}, {Destroyed =0 ; Created=1}] }; // <-- this is the first reaction because propensity = Rate => ln(1/r1)/propensity is small
            { Rate = 1000.0 ; Changes = dict[ {Name = "S"}, {Destroyed =1 ; Created=0}] }  ]
        let result = executeNextReaction reactions 0.0 rnd system
        Assert.AreEqual ( reactions.[3], result.UpdatedSystem )
end